import { Component, forwardRef, Input, OnInit } from '@angular/core';
import { UploadFile } from '@shared/apes/upload';
import { toBoolean, toNumber } from '@shared/apes/core/util/convert';
import { ApiService } from '@core/services/http/api.service';
import { ApesMessageService } from '@shared/apes/message';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { saveAs } from 'file-saver';
import { dateFormat, deepClone, type } from '../../utils/utils';
import { ApesPreviewDialogComponent } from '@shared/ag-grid-ext/upload-component/apes-previewDialog.component';
import { ApesModalService } from '@shared/apes/modal';
import { InputBoolean } from '@shared/apes/core';
import { ExpressionService } from '@core/services/expression/ExpressionService';
import { DomSanitizer } from '@angular/platform-browser';
import { XlsxService } from '@shared/apes/xlsx';

@Component({
  selector: 'upload',
  templateUrl: './upload.component.html',
  styleUrls: ['./upload.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => UploadComponent),
      multi: true,
    },
  ],
})
export class UploadComponent implements OnInit, ControlValueAccessor {
  uploading = false;
  _fileList: UploadFile[] = [];
  previewImage = '';
  previewVisible = false;
  showList: any;
  imgType: any = 'image/png,image/jpeg,image/gif,image/bmp';
  @Input() api;
  @Input() disabled;
  @Input() type: any;
  @Input() limit: any;
  @Input() @InputBoolean() showDownload: any;
  @Input() @InputBoolean() showRemove: any;
  @Input() @InputBoolean() showCarousel: boolean = false;
  @Input() showPreviewFormatter: any;
  @Input() formState: any;

  importData: any = [];
  @Input() parsing: any = 'upload';

  pdfPreview: boolean = false;
  preview: any;

  onChange: (value: any) => void = () => null;
  onTouched: () => void = () => null;

  constructor(
    private  apiService: ApiService,
    private msg: ApesMessageService,
    private modalService: ApesModalService,
    protected expressionService: ExpressionService,
    private sanitizer: DomSanitizer,
    private xlsx: XlsxService,
  ) {
  }

  ngOnInit() {
    // console.log('showDownload',this.showDownload);
  }

  get fileList(): UploadFile[] {
    return this._fileList || [];
  }

  set fileList(input: UploadFile[]) {
    let value = input;
    if (this._fileList === value) {
      return;
    }
    this._fileList = value;
  }

  /** 显示数量 **/
  showLimit() {
    // let _limit
    return this.limit ? '允许上传最多' + this.limit + '个文件' : '不限个数';
  }

  /** 控制上传类型、数量和是否重复**/
  beforeUpload = (file: UploadFile): boolean => {
    let _type = this.type ? this.type : file.type;
    let _limit = toNumber(this.limit, null);
    let tempFileList = this.fileList;
    let isRepeat = false;
    if (_type.indexOf(file.type) == -1 || (file.type == '' && _type != file.type)) {
      this.msg.error('请上传指定类型文件');
      return false;
    }
    if (this.uploading) {
      this.msg.error('有文件上传中，请稍后再传！');
      return false;
    }
    if (_limit !== null) {
      if (this.fileList.length < _limit) {
        if (this.fileList.length == 0) {
          this.fileList.push(file);
        } else {
          tempFileList.map((files) => {
            if (files.name == file.name) {
              isRepeat = true;
            }
          });
          if (isRepeat) {
            this.msg.error('请勿重复上传相同文件');
            return false;
          } else {
            this.fileList.push(file);
          }
        }
      } else {
        this.msg.error('超出上传限制数量');
        return false;
      }
    } else {
      this.fileList.push(file);
    }

    if (this.parsing == 'upload') {
      this.handleUpload();
    } else if (this.parsing == 'excel') {
      this.importData = [];
      const item: any = this.fileList[0];
      this.xlsx.import(item).then((res) => {
        this.importData = res;
        this.onChange(this.fileList);
      });
    }
    return false;
  };

  /** 上传操作 **/
  handleUpload(): void {
    // 判断
    this.uploading = true;
    this.apiService.upload(this.fileList, this.api).subscribe(
      (event: any) => {
        const returnFile = event.body;
        // this.formControl.patchValue(returnFile);
        // this.model[this.key] = returnFile;
        this.showFilesList(returnFile);
        this.msg.success('上传成功');
        this.uploading = false;
      },
      err => {
        console.log(err);
        this.uploading = false;
        this.msg.error('上传失败,请核实文件是否能正常上传！');
      },
    );
  }

  /** 处理上传文件 **/
  showFilesList(returnFile) {
    let tempFileList = this.fileList.filter(x => x.lastModified == undefined);
    returnFile.map((file) => {
      if (!file.url && file.id && this.imgType.indexOf(file.type) > -1) {
        file.url = 'fileserver/view/' + file.id;
      }
      tempFileList.push(file);
    });
    this.fileList = tempFileList;
    this.onChange(this.fileList);
  }

  /** 删除文件 **/
  handleRemove = (file: UploadFile) => {
    if (this.disabled) return false;
    this.fileList = this.fileList.filter(x => x.name !== file.name);
    this.onChange(this.fileList);
    return true;
  };

  /** 下载文件 **/
  handleDownload() {
    this.apiService.download(this.fileList).subscribe(
      (event: any) => {
        let fileName = dateFormat('yyyyMMddHHmmss', new Date());
        let body = event.body;
        if (body.type === 'application/octet-stream') {
          saveAs(body, decodeURI(`${fileName}.zip`));
        }
      },
    );
  };

  /** 是否允许下载 **/
  handleShowList = () => {
    let showDownload = this.showDownload || false;
    let showRemove = this.showRemove || true;
    this.showList = {
      showPreviewIcon: true,
      showRemoveIcon: toBoolean(showRemove),
      showDownloadIcon: toBoolean(showDownload),
    };
    return this.showList;
  };

  /** 判断是否显示预览图 **/
  handlePreview = (file: UploadFile) => {
    if (this.showCarousel) {
      this.showCarouselDailog();
    } else {
      if (file.type && file.type.indexOf('image') > -1) {
        // if (file.url) {
        //   this.previewImage = file.url;
        // } else {
        //   this.previewImage = 'fileserver/view/' + file.id || file.thumbUrl;
        // }
        if (this.showPreviewFormatter) {
          this.previewVisible = this.expressionService.eval(this.showPreviewFormatter, {
            context: this.formState,
            model: this.formState.model,
          });
        } else {
          this.previewVisible = true;
        }

        if(this.previewVisible){
          this.showCarouselDailog(file);
        }
      } else if (file.type && file.type.indexOf('pdf') > -1) {
        this.pdfPreview = true;
        this.preview = this.sanitizer.bypassSecurityTrustResourceUrl('fileserver/view/' + file.id);
      }
    }
  };

  showCarouselDailog(file?) {
    let dialog: any;
    let fileList = file ? [deepClone(file)] : deepClone(this.fileList);
    let option = {
      title: '预览图片',
      _fileList: fileList,
    };

    const openDialog = dialog ? dialog : ApesPreviewDialogComponent;
    const dialogRef = this.modalService.create({
      apesWidth: '45vw',
      apesTitle: option.title,
      apesContent: openDialog,
      apesComponentParams: option,
      apesFooter: [
        {
          label: '取消',
          type: 'default',
          onClick: () => {
            dialogRef.close();
          },
        },
        {
          label: '确定',
          type: 'primary',
          onClick: (componentInstance) => {
            dialogRef.destroy(componentInstance['fileList']);
          },
        },
      ],
    });

    return dialogRef.afterClose.subscribe((result) => console.log(result));
  }

  writeValue(value: any): void {
    let t = type(value);
    if (t != 'file' && t != 'array') {
      this.fileList = JSON.parse(value) || [];
    }
  }

  registerOnChange(fn: (_: any) => void): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: () => void): void {
    this.onTouched = fn;
  }

}
